/*
  Copyright (c) 2014-2015 NicoHood
  See the readme for credit to other people.

  Improved Keyboard example

  Shows how to use the new Keyboard API.

  See HID Project documentation for more information.
  https://github.com/NicoHood/HID/wiki/Keyboard-API#improved-keyboard
*/

#include "HID-Project.h"


/*
 *                    S1(D14)   S2(D15)  
 *       A2                                                       /
 *                    5(D2)   6(D4)   7(D6)   8(D8)              /    C1(D10) 
 *   A1       A3                                                / 
 *                    1(D3)   2(D5)   3(D7)   4(D9)            /    c2(D16)
 *       A0                                                   /
 *                                                           /
 */
  //屏中心坐标是0,0,最左边是32768/2=-16384 最右边是16384,最上边是-16384,最下边是16384
#define SWIDTH 32768
#define SHEIGHT 1080
#define MAXMOUSE 32760
#define KB1  KEY_Q
#define KB2  KEY_W
#define KB3  KEY_E
#define KB4               //鼠标左键
#define KB5  KEY_SPACE    //空格键,攻击当前目标
#define KB6  KEY_D
#define KB7  KEY_F     
#define KB8 KEY_LEFT_ALT  //ALT按键
#define KBS1 KEY_A        //按键A
#define KBS2 KEY_R        //按键R
#define KBC1 KEY_ESC             //ESC键,关闭所有打开的窗口界面
#define KBC2             //是否开启鼠标左键

#define LMOVEP 15
#define RMOVEP_X 80
#define RMOVEP_Y 150
#define REDELAY 6

const int btn1 = 3;
const int btn2 = 5;
const int btn3 = 7;
const int btn4 = 9;
const int btn5 = 2;
const int btn6 = 4;
const int btn7 = 6;
const int btn8 = 8;
const int btnS1 = 14;
const int btnS2 = 15;

const int btnC1 = 10;
const int btnC2 = 16;

//const int bUp = A2;
//const int bRight = A3;
//const int bDown = A0;
//const int bLeft = A1;

const int bUp = A0;
const int bLeft = A2;
const int bRight = A1;
const int bDown = A3;


int mX = 0;     //屏中心x坐标
int mY = int(32768*0.38-16384);    //屏中心y坐标

int lmoveP = int((LMOVEP/1920.0)*32768);
int rmovePX = int((RMOVEP_X/1080.0)*32768);
int rmovePY = int((RMOVEP_Y/1080.0)*32768);

int32_t x = 0;
int32_t y = 0;

bool isLeftMove = false;

const int pinLed = LED_BUILTIN;
// const int pinButton = 2;

void setup() {
  pinMode(pinLed, OUTPUT);
  pinMode(btn1, INPUT_PULLUP);
  pinMode(btn2, INPUT_PULLUP);
  pinMode(btn3, INPUT_PULLUP);
  pinMode(btn4, INPUT_PULLUP);  //做为左键
  pinMode(btn5, INPUT_PULLUP);
  pinMode(btn6, INPUT_PULLUP);
  pinMode(btn7, INPUT_PULLUP);
  pinMode(btn8, INPUT_PULLUP);
  pinMode(btnS1, INPUT_PULLUP);
  pinMode(btnS2, INPUT_PULLUP);
  pinMode(btnC1, INPUT_PULLUP);
  pinMode(btnC2, INPUT_PULLUP);
  
  pinMode(bUp, INPUT_PULLUP);
  pinMode(bRight, INPUT_PULLUP);
  pinMode(bDown, INPUT_PULLUP);
  pinMode(bLeft, INPUT_PULLUP);


  // Sends a clean report to the host. This is important on any Arduino type.
  AbsoluteMouse.begin();
  Keyboard.begin();

}

#define SET_STATE(ST) (ST |= (uint32_t)1<<1)
#define UNSET_STATE(ST) (ST &= ~((uint32_t)1 << 1))

bool touchOnce = false;

void loop() {
  digitalWrite(pinLed, HIGH);
  int32_t lastX = x;
  int32_t lastY = y;
  if (!digitalRead(btn1)) {
    Keyboard.press(KB1); 
  }else{
    Keyboard.release(KB1);
  }
  if (!digitalRead(btn2)) {
    Keyboard.press(KB2);
  }
  else{
    Keyboard.release(KB2);
  }
  if (!digitalRead(btn3)) {
    Keyboard.press(KB3);
  }else{
    Keyboard.release(KB3);
  }
  if (!digitalRead(btn4)) {
    // Keyboard.press(KB4);
    AbsoluteMouse.press();
  }else{
    AbsoluteMouse.release();
  }
  if (!digitalRead(btn5)) {
    Keyboard.press(KB5);
  }else{
    Keyboard.release(KB5);
  }
  if (!digitalRead(btn6)) {
    Keyboard.press(KB6);
  }
  else{
    Keyboard.release(KB6);
  }
  if (!digitalRead(btn7)) {
    Keyboard.press(KB7);
  }else{
    Keyboard.release(KB7);
  }
  if (!digitalRead(btn8)) {
    Keyboard.press(KB8);
  }else{
    Keyboard.release(KB8);
  }

  if (!digitalRead(btnS1)) {
    Keyboard.press(KBS1);
  }else{
    Keyboard.release(KBS1);
  }
  if (!digitalRead(btnS2)) {
    Keyboard.press(KBS2);
  }else{
    Keyboard.release(KBS2);
  }

  if (!digitalRead(btnC1)) {
    Keyboard.press(KBC1);
  }else{
    Keyboard.release(KBC1);
  }
  if (!digitalRead(btnC2)) {
    // Keyboard.press(KBC2);
    touchOnce = true;
  }else{
    // Keyboard.release(KBC2);
    if(touchOnce){
      isLeftMove = !isLeftMove;
      touchOnce = false;
    }
  }

  bool isup = !digitalRead(bUp);
  bool isright = !digitalRead(bRight);
  bool isdown = !digitalRead(bDown);
  bool isleft = !digitalRead(bLeft);


  //摇杆向上
    if(isup){
      //鼠标右键按下并向上移动一段距离,这时角色会向上移动
      if(isLeftMove){
        y = y - lmoveP;
      }else{
        y = mY - rmovePY;
      }
    }else{
      if(!isLeftMove){
        y = mY;
      }
    }
  //摇杆向下
    if(isdown){
      //鼠标右键按下并向下移动一段距离,这时角色会向下移动
      if(isLeftMove){
        y = y + lmoveP;
      }else{
        y = mY + rmovePY;
      }
    }
    if(!(isdown || isup) && !isLeftMove){
      y = mY;
    }
  //摇杆向左
    if(isleft){
      //鼠标右键按下并向左移动一段距离,这时角色会向左移动
      if(isLeftMove){
        x = x - lmoveP;
      }else{
        x = mX - rmovePX;
      }
    }
  //摇杆向右
    if(isright){
      //鼠标右键按下并向右移动一段距离,这时角色会向右移动
      if(isLeftMove){
        x = x + lmoveP;
      }else{
        x = mX + rmovePX;
      }
    }
    if(!(isright || isleft) && !isLeftMove){
      x = mX;
    }
  if(isLeftMove){
    if(x > MAXMOUSE){
        x = MAXMOUSE;
      }else if(x < -MAXMOUSE){
        x = -MAXMOUSE;
      }
      if(y > MAXMOUSE){
        y = MAXMOUSE;
      }else if(y < -MAXMOUSE){
        y = -MAXMOUSE;
      }
    AbsoluteMouse.moveTo(x, y);
  }else{
    if(lastX != x || lastY != y){
      //方向状态改变,向PC发送鼠标状态
      if(x > MAXMOUSE){
        x = MAXMOUSE;
      }else if(x < -MAXMOUSE){
        x = -MAXMOUSE;
      }
      if(y > MAXMOUSE){
        y = MAXMOUSE;
      }else if(y < -MAXMOUSE){
        y = -MAXMOUSE;
      }
      AbsoluteMouse.moveTo(x,y);
    }
    if(isup || isdown || isleft || isright){
      AbsoluteMouse.press(MOUSE_RIGHT);
    }else{
      AbsoluteMouse.release(MOUSE_RIGHT);
    }
  }
  delay(REDELAY);
  digitalWrite(pinLed, LOW);

}
